/*
 * sgc_chat_connections.c
 *
 *  Created on: 2011-7-11
 *      Author: rendong
 */
#include "sgc_connections.h"
#include <unistd.h>

sgc_inthash_table_t * sgc_all_sessions; //  fd => session

/**
 * 新用户连接
 */
void chat_client_new_handler(int fd, struct sockaddr_in *clientaddr,  sgc_epoll_socketserver_config_t const* config)
{
	sgc_chat_session_t * session = (sgc_chat_session_t*) malloc(sizeof(sgc_chat_session_t));
	memset(session, 0, sizeof(sgc_chat_session_t));
	session->fd = fd;
	session->buffer = (char *)malloc(cfg_user_buffersize+1);
	memset(session->buffer, 0, cfg_user_buffersize + 1);
	session->buffersize = cfg_user_buffersize;
	session->bufferpos = 0;

	struct sockaddr_in *client = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));
	memcpy(client, clientaddr, sizeof(struct sockaddr_in));
	session->clientaddr = client;

	session->config = config;

	if (sgc_inthash_put(sgc_all_sessions, fd, session))
	{
		sgc_log_error("fd exists:%d, %s\n", fd, inet_ntoa(clientaddr->sin_addr));
	}
}

/**
 * 消息处理
 */
void chat_client_message_handler(int fd, char const * buffer, int length)
{
	sgc_chat_session_t * session = sgc_inthash_get(sgc_all_sessions, fd);
	if (session == NULL){
		sgc_log_error("session not found,fd=%d\n", fd);
		return;
	}

	int remain = session->buffersize - session->bufferpos;
	if (remain < length)
	{
		sgc_log_error("buffer full fd=%d\n", fd);
		session->config->do_close(fd, session->config);
		return;
	}

	memcpy(session->buffer+session->bufferpos, buffer, length);
	session->bufferpos += length;

	int len = sizeof("<policy-file-request/>") -1;

	if (strncmp(session->buffer, "<policy-file-request/>", len) == 0){
		writen(session->fd, cross_domain_policy, cross_domain_policy_size);
		session->config->do_close(fd, session->config);
	}
}

/**
 * 关闭
 */
void chat_client_close_hander(int fd)
{
	sgc_chat_session_t * session = sgc_inthash_get(sgc_all_sessions, fd);

	// 释放和session相关的内存
	if (session != NULL){
		sgc_inthash_del(sgc_all_sessions, fd);

		session->config = NULL;
		free(session->clientaddr);
		free(session->buffer);
		free(session);
	}

	sgc_log_debug("epoll_client_close_hander_t fd:%d\n", fd);
}

/**
 * 启动服务
 */
void sgc_start_chat_server()
{
	// 初始化数据
	sgc_all_sessions = (sgc_inthash_table_t *)malloc(sizeof(sgc_inthash_table_t));
	sgc_inthash_init(sgc_all_sessions, cfg_maxclients);

	int capacity = cfg_maxclients / 100;
	if (capacity < 100)
		capacity = 100;

	// 初始化配置
	sgc_epoll_socketserver_config_t config;
	config.buffer_size = cfg_buffersize;
	config.local_addr = cfg_local_addr;
	config.port = cfg_port;
	config.maxclients = cfg_maxclients;

	config.handler_new = chat_client_new_handler;
	config.hander_read = chat_client_message_handler;
	config.hander_close = chat_client_close_hander;

	sgc_serversocket_start(&config);
}
